package org.paraj.misc;

import org.springframework.remoting.rmi.RmiServiceExporter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class RmiExporter {
    private Registry registry;

    public RmiExporter() throws RemoteException {
//        init();
    }

    public void export(Object remote, final String name, final Class interface_){
        try {
            RmiServiceExporter exporter = new RmiServiceExporter();
//            exporter.setAlwaysCreateRegistry(true);
            exporter.setServiceName(name);
            exporter.setService(remote);
            exporter.setServiceInterface(interface_);
            exporter.afterPropertiesSet();

//            Remote remote = wrapWithRemoteInterface(o, interfaces);
//            Remote stub = UnicastRemoteObject.exportObject(remote, 0);
            
//            registry.rebind(name, stub);
        } catch (Exception e) {
            throw new EnvironmentException("Can not bind "+name, e);
        }
    }

    private Remote wrapWithRemoteInterface(Object o, Class... interfaces) {
        List<Class> interfaces1 = new ArrayList<Class>();
        interfaces1.addAll(Arrays.asList(interfaces));
        interfaces1.add(Remote.class);
        Remote remoteProxy = (Remote) Proxy.newProxyInstance(o.getClass().getClassLoader(), interfaces1.toArray(new Class[0]), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(proxy, args);
            }
        });
        return remoteProxy;
    }

    private void init() throws RemoteException {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }
        try {
            registry = LocateRegistry.getRegistry();
            registry.list();
        } catch (RemoteException e) {
            registry = LocateRegistry.createRegistry(1099);
            System.out.println("RMI registry ready.");
        }
    }


}
